package Test1;

/*
Dijkstra算法思想：采用贪心法思想，进行n-1次查找（PS:n为加权连通图的顶点总个数，
除去起点，则剩下n-1个顶点），第一次进行查找，找出距离起点最近的一个顶点，标记为已遍历；
下一次进行查找时，从未被遍历中的顶点寻找距离起点最近的一个顶点， 标记为已遍历；
直到n-1次查找完毕，结束查找，返回最终结果

 */
public class Dijkstra {
    /*
     * 参数adjMatrix:为图的权重矩阵，权值为-1的两个顶点表示不能直接相连
     * 函数功能：返回顶点0到其它所有顶点的最短距离，其中顶点0到顶点0的最短距离为0
     */
    public int[] getShortestPaths(int[][] adjMatrix) {
        int[] result = new int[adjMatrix.length];   //用于存放顶点0到其它顶点的最短距离
        boolean[] used = new boolean[adjMatrix.length];  //用于判断顶点是否被遍历
        used[0] = true;  //表示顶点0已被遍历
        for(int i = 1;i < adjMatrix.length;i++) {
            result[i] = adjMatrix[0][i];
            used[i] = false;
        }

        for(int i = 1;i < adjMatrix.length;i++) {
            int min = Integer.MAX_VALUE;    //用于暂时存放顶点0到i的最短距离，初始化为Integer型最大值
            int k = 0;
            for(int j = 1;j < adjMatrix.length;j++) {  //找到顶点0到其它顶点中距离最小的一个顶点
                if(!used[j] && result[j] != -1 && min > result[j]) {
                    min = result[j];
                    k = j;
                }
            }
            used[k] = true;    //将距离最小的顶点，记为已遍历
            for(int j = 1;j < adjMatrix.length;j++) {  //然后，将顶点0到其它顶点的距离与加入中间顶点k之后的距离进行比较，更新最短距离
                if(!used[j]) {  //当顶点j未被遍历时
    //首先，顶点k到顶点j要能通行；这时，当顶点0到顶点j的距离大于顶点0到k再到j的距离或者顶点0无法直接到达顶点j时，更新顶点0到顶点j的最短距离
                    if(adjMatrix[k][j] != -1 && (result[j] > min + adjMatrix[k][j] || result[j] == -1))
                        result[j] = min + adjMatrix[k][j];
                }
            }
        }
        return result;
    }

    public static void main(String[] args) {
        Dijkstra test = new Dijkstra();
        int INF=-1;
        int[][] adjMatrix = {
                /*1*//*2*//*3*//*4*//*5*//*6*/
                /*1*/ {   0,  30, INF, 50,  20,  30},
                /*2*/ { INF,   0,  40, INF, 20, INF},
                /*3*/ { INF, INF,   0, INF,  50,  30},
                /*4*/ { INF, INF,  30,   0, INF, 40},
                /*5*/ { INF, INF, INF,  20,   0,  70},
                /*6*/ { INF, INF, 50, 100, INF,   0},

        };
        int[] result = test.getShortestPaths(adjMatrix);
        System.out.println("Vertex\tDistance");
        for(int i = 0;i < result.length;i++)
            System.out.println((i+1) +"\t\t"+ result[i]+" ");
    }
}

